package com.qianyitian.hope2.analyzer.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.qianyitian.hope2.analyzer.analyzer.EStockAnalyzer;
import com.qianyitian.hope2.analyzer.analyzer.IStockAnalyzer;
import com.qianyitian.hope2.analyzer.analyzer.StockAnalyzerFacotry;
import com.qianyitian.hope2.analyzer.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 *
 */
@Service("gradeScoreService")
public class GradeScoreService {
    private Logger logger = LoggerFactory.getLogger(getClass());
    public static final String STOCK_GRADE_STORE_KEY = "stock-grade-hash";
    public static final String STOCK_GRADE_REPORT_KEY = "stock-grade-report";
    public static final String STOCK_GRADE_REPORT_LITE_KEY = "stock-grade-lite-report";

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    StockAnalyzerFacotry stockAnalyzerFacotry;

    @Autowired
    private StockService stockService;

    public GradeScoreService() {
    }

    public void grade() {
        StockGrader sg = new StockGrader();
        for (EStockAnalyzer enumAnalyzer : EStockAnalyzer.values()) {
            IStockAnalyzer analyzer = stockAnalyzerFacotry.getStockAnalyzer(enumAnalyzer);
            sg.addAnalyzer(analyzer);
        }

        SymbolList symbols = stockService.getSymbols(null);
        for (Stock symbol : symbols.getSymbols()) {
            Stock stock = stockService.getStockDailySA(symbol.getCode());
            Map map = sg.startGrade(stock);
            storeGrade(symbol.getCode(), map);
        }
        genGradeReport();
    }


    private void storeGrade(String code, Map<String, Integer> gradeScore) {
        String json = JSON.toJSONString(gradeScore);
        redisTemplate.opsForHash().put(STOCK_GRADE_STORE_KEY, code, json);
    }

    private int genGradeReport() {
        List list = redisTemplate.opsForHash().values(STOCK_GRADE_STORE_KEY);

        List<JSONObject> result = (List<JSONObject>) list.stream().map(item -> {
            String stock = (String) item;
            JSONObject jsonObject = JSON.parseObject(stock);
            return jsonObject;
        }).filter(stock -> {
            return stock != null;
        }).collect(Collectors.toList());
        int size = result.size();
        {
            Map map = new HashMap();
            map.put("items", result);
            map.put("generateTime", LocalDateTime.now().toString());
            String content = JSON.toJSONString(map);
            redisTemplate.opsForValue().set(STOCK_GRADE_REPORT_KEY, content);
        }

        {

            result = result.stream().sorted((a, b) ->
                    b.getInteger("total").compareTo(a.getInteger("total"))
            ).limit(200).collect(Collectors.toList());
            Map map = new HashMap();
            map.put("items", result);
            map.put("generateTime", LocalDateTime.now().toString());
            String content = JSON.toJSONString(map);
            redisTemplate.opsForValue().set(STOCK_GRADE_REPORT_LITE_KEY, content);
        }


        return size;
    }


    public String getAllStockGrade() {
        String content = redisTemplate.opsForValue().get(STOCK_GRADE_REPORT_KEY);
        return content;
    }

    public String getAllStockGradeLite() {
        String content = redisTemplate.opsForValue().get(STOCK_GRADE_REPORT_LITE_KEY);
        return content;
    }
}
